/* ------------------------------------------------------------------------
 *
 * tipc.h
 *
 * Short description: TIPC header file
 * 
 * ------------------------------------------------------------------------
 *
 * Copyright (c) 2003, Ericsson Research Canada
 * Copyright (c) 2004, 2005 Wind River Systems, Inc.
 * All rights reserved.
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this 
 * list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, 
 * this list of conditions and the following disclaimer in the documentation 
 * and/or other materials provided with the distribution.
 * Neither the names of the copyright holders nor the names of its 
 * contributors may be used to endorse or promote products derived from this 
 * software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * ------------------------------------------------------------------------
 *
 *  Created 2003-10-20 by Jon Maloy
 *
 * ------------------------------------------------------------------------
 *
 *  Revision history:
 *  ----------------
 *
 *  PA1	2003-10-20	Jon Maloy	Created.
 *
 * ------------------------------------------------------------------------
 * modification history
 * --------------------
 * 01j,12may05,als  update AF_TIPC to avoid conflict with AF_ATM
 * 01i,08apr05,als  consolidate copyright info; fix compiler inlining warnings 
 * 01h,08feb05,bwa  added shared memory address type.
 * 01g,15dec04,als  add support for poll()-like events
 * 01f,25oct04,als  fix comment
 * 01e,05oct04,als  Fix misleading comment
 * 01d,14sep04,als  name table display enhancements
 * 01c,03sep04,als  incorporated code inspection feedback
 * 01b,07aug04,p_r  code update
 * 01a,30jun04,als  Ported to VxWorks
 *
 */

#ifndef __NET_TIPC_H_
#define __NET_TIPC_H_

#ifdef __cplusplus
extern "C" {
#endif

#include <vxWorks.h>
#include <sys/socket.h>

/* Scalar data types used by TIPC (WRS) */

typedef	unsigned char  	__u8, unchar;
typedef	char		__s8;
typedef	unsigned short	__u16;
typedef	short		__s16;
typedef	unsigned int    __u32, uint;
typedef	int		__s32;


/*
 * TIPC addressing primitives
 *
 * (Uses macros rather than inline functions to avoid compiler warnings)
 */
struct tipc_portid {
	__u32 ref;
	__u32 node;
};

struct tipc_name {
	__u32 type;
	__u32 instance;
};

struct tipc_name_seq {
	__u32 type;
	__u32 lower;
	__u32 upper;
};

#define tipc_addr(Z,C,N) (((Z)<<24)|((C)<<12)|(N))
#define tipc_zone(A)     ((A)>> 24)
#define tipc_cluster(A)  (((A) >> 12) & 0xfff)
#define tipc_node(A)     ((A) & 0xfff)


/* 
 * Binding scopes for port names and port name sequences:
 */
#define TIPC_ZONE_SCOPE         1
#define TIPC_CLUSTER_SCOPE      2     
#define TIPC_NODE_SCOPE         3

/* 
 * Message importance levels:
 */
#define TIPC_LOW_IMPORTANCE     0       /* default importance level */
#define TIPC_NORMAL_IMPORTANCE	1       /* actually means "medium importance" */
#define TIPC_HIGH_IMPORTANCE	2
#define TIPC_NON_REJECTABLE	3

/* 
 * Topology event values:
 */
#define TIPC_PUBLISHED          1
#define TIPC_WITHDRAWN          2
#define TIPC_SUBSCR_TIMEOUT     3  

/* 
 * Msg rejection/connection shutdown reasons:
 */
#define TIPC_CONN_SHUTDOWN      0x0010 
#define TIPC_ERR_NO_NAME        0x1000
#define TIPC_ERR_NO_PORT	0x2000
#define TIPC_ERR_NO_NODE	0x4000
#define TIPC_ERR_OVERLOAD	0x8000


#define TIPC_MAX_MSG_SIZE      66000
#define TIPC_MAX_SECTION_COUNT 128

/*
 * Socket interface:
 * -----------------
 */

#ifndef AF_TIPC
#define AF_TIPC	33
#endif

#define TIPC_ADDR_NAMESEQ   	1
#define TIPC_ADDR_MCAST         1
#define TIPC_ADDR_NAME      	2
#define TIPC_ADDR_ID        	3


struct sockaddr_tipc {
	unsigned char  addrlen;                 /* 16 (WRS only) */
	unsigned char  family;                  /* AF_TIPC */
	unsigned char  addrtype;                /* TIPC_ADDR_xxx */
	unsigned char  scope;                   /* used with bind */
	union {
		struct tipc_portid id;          /* if TIPC_ADDR_ID */
		struct tipc_name_seq nameseq;   /* if TIPC_ADDR_NAMESEQ/_MCAST */
		struct {                        /* if TIPC_ADDR_NAME */
			struct tipc_name name;
			__u32 domain;           /* used with connect, sendto */
		} name;
	} addr;
};

/*
 * Poll events from TIPC sockets. May be combined with 
 * previously defined reject/shutdown reasons
 */
#define TIPC_MSG_PENDING     0x0041 /* POLLRDNORM|POLLIN */
#define TIPC_UNDELIVERED_MSG 0x0049 /* POLLRDNORM|POLLERR|POLLIN */
#define TIPC_CONN_ABORT      0x0018 /* POLLHUP|POLLERR   */
#define TIPC_TOPOLOGY_EVENT  0x0800    

/*
 * Parameters for getsockopt() and setsockopt():
 */
#define SOL_TIPC		50
#define IMPORTANCE_OPTION	127	/* Default: LOW_IMPORTANCE */
#define UNRELIABLE_OPTION	128	/* Default: reliable,no args */
#define O_NONBLOCK_OPTION	129	/* Default: blocking read  */
#define CONN_ACK_TIMEOUT     	130	/* Default: 8000 ms  */
#define TIPC_POLLEVENTS         131     /* Get/clear poll() events (get only) */

/*
 * TIPC topology services definitions.
 *
 * Subscriptions fire repeatedly on any event until cancelled or
 * until the timeout expires. Need not be cancelled after timeout.
 *
 * Details about a fired/expired subscription MUST be obtained 
 * using the GET_EVENT command or BLOCK_GET_EVENT command (WRS only).
 *
 * Availability of nodes is obtained by using the special "type" 0: 
 * e.g.<type,lower,upper> == <0,tipc_addr(z,c,0),tipc_addr(z,c,0xfff)> 
 */

struct tipc_subscr {
	struct tipc_name_seq seq;
	__u32 timeout;	/* [ms] */
	__u32 ref;
        __u32 all;        /* All events, or available/unavailable */
	char usr_handle[8];
};
#define TIPC_SUBSCRIBE      300 /* ioctl(tipc_subscr*)    */
#define TIPC_UNSUBSCRIBE    301	/* ioctl(tipc_subscr.ref) */
#define TIPC_WAIT_FOREVER   ~0

struct tipc_event {
	__u32 event;
	__u32 found_lower;
	__u32 found_upper;
        struct tipc_portid port;
	struct tipc_subscr s;
};
#define TIPC_GET_EVENT      173	/* ioctl(tipc_event*) */
#define TIPC_BLOCK_GET_EVENT  182	/* ioctl(tipc_event*) (WRS only) */

/* 
 * Blocking subscription for availability of port name.
 * No cancelling needed.
 */
struct tipc_block_subscr{
        struct tipc_name name;
        unsigned int timeout;  
        int is_published; /* Return value */
};

#define TIPC_BLOCK_SUBSCRIBE 175 /* Takes tipc_block_subscr* */

/*
 * More ioctls:
 */
#define TIPC_OWN_NODE      177 /* Takes __u32*              */
#define TIPC_UNBIND        178 /* Takes tipc_name_seq* or zero        */

#if 0   /* NOT SUPPORTED BY WRS */
#define TIPC_CONNECT       179 /* Local connect. Takes sockaddr_tipc* */
#define TIPC_DISCONNECT    180 /* Local disconnect.                   */
#endif

#define TIPC_GET_DEST_ADDR 181 /* Destination of received msg. 
                                  Takes sockaddr_tipc*                */
                                  
#if 0   /* NOT SUPPORTED BY WRS */
/*
 * Flag for SOCK_SEQPACKET/recv(): return and consume  pending 
 * message if it fits into the buffer. Otherwise put pending msg
 * length into the first four bytes of buffer and return 0
 */
#define MSG_PEEP 0x8000
#endif

/* 
 * Port interface:
 * --------------
 */

__u32 tipc_own_node(void);

/* 
 * Return codes:
 */
#define TIPC_OK 0
#define TIPC_FAILURE -22
#define TIPC_CONGESTION -2


struct tipc_msg_section {
	unsigned char const *data;
	unsigned int size;
};

#define TIPC_NOT_RUNNING  0
#define TIPC_NODE_MODE    1
#define TIPC_NET_MODE     2

typedef void (*tipc_mode_event) (void *usr_handle,
                                 int mode,
                                 __u32 addr);

int tipc_attach(unsigned int *userref,
		tipc_mode_event, void *usr_handle);

void tipc_detach(unsigned int userref);

int tipc_get_mode(void);

typedef void (*tipc_conn_shutdown_event) (void *usr_handle,
                                          __u32 portref,
                                          unsigned char const *data,
                                          unsigned int size,
                                          int reason, 
                                          void **buf);

typedef void (*tipc_msg_err_event) (void * usr_handle,
		     __u32 portref,
		     unsigned char const *data,
		     unsigned int size,
		     struct tipc_portid const *attmpt_destid,
		     int reason, 
                     void **buf);

typedef void (*tipc_named_msg_err_event) (void * usr_handle,
		     __u32 portref,
		     unsigned char const *data,
		     unsigned int size,
		     struct tipc_name_seq const *attmpt_dest,
		     int reason, 
                     void **buf);

typedef void (*tipc_msg_event) (void * usr_handle,
				__u32 portref,
				unsigned char const *data,
				unsigned int size,
				struct tipc_portid const *origin,
				unsigned int importance, 
                                void **buf);

typedef void (*tipc_named_msg_event) (void *usr_handle,
				      __u32 portref,
				      unsigned char const *data,
				      unsigned int size,
				      struct tipc_portid const *orig,
				      struct tipc_name_seq const *dest,
				      unsigned int importance, 
                                      void **buf);

typedef void (*tipc_conn_msg_event) (void *usr_handle,
				     __u32 portref,
				     unsigned char const *data,
				     unsigned int size, 
                                     void **buf);

typedef void (*tipc_continue_event) (void *usr_handle, __u32 portref);

int tipc_createport(unsigned int tipc_user, 
		    void * usr_handle, 
		    unsigned int importance, 
		    tipc_msg_err_event error_cb, 
		    tipc_named_msg_err_event named_error_cb, 
		    tipc_conn_shutdown_event conn_error_cb, 
		    tipc_msg_event message_cb, 
		    tipc_named_msg_event named_message_cb, 
		    tipc_conn_msg_event conn_message_cb, 
		    tipc_continue_event continue_event_cb,/* May be zero */
		    __u32 *portref);

int tipc_deleteport(__u32 portref);

int tipc_ownidentity(__u32 portref, struct tipc_portid *port);

int tipc_portimportance(__u32 portref, unsigned int *importance);

int tipc_set_portimportance(__u32 portref,
			   unsigned int importance);

int tipc_set_unreliable(__u32 portref);

int tipc_publish(__u32 portref,
		 unsigned int scope,
		 struct tipc_name_seq const *);

int tipc_withdraw(__u32 portref,
                  struct tipc_name_seq const *); /* 0: all */

int tipc_connect2port(__u32 portref,
		      struct tipc_portid const *port);

int tipc_disconnect(__u32 portref);

int tipc_shutdown(__u32 ref); /* Sends SHUTDOWN msg */

int tipc_isconnected(__u32 portref, int *isconnected);

int tipc_peer(__u32 portref, struct tipc_portid *peer);

int tipc_ref_valid(__u32 portref); 

int tipc_send(__u32 portref,
	      unsigned int section_count,
	      struct tipc_msg_section const *msg);

int tipc_send_buf(__u32 ref,
		  void *buf,
                  uint size);

int tipc_send2name(__u32 portref, 
		   struct tipc_name const *name, 
		   __u32 domain,	/* 0:own zone */
		   unsigned int section_count,
		   struct tipc_msg_section const *msg);

int tipc_send_buf2name(__u32 ref,
		       struct tipc_name const *name,
                       __u32 domain,
		       void *buf,
                       uint size);

int tipc_send2port(__u32 portref,
		   struct tipc_portid const *dest,
		   unsigned int section_count,
		   struct tipc_msg_section const *msg);

int tipc_send_buf2port(__u32 ref,
		       struct tipc_portid const *dest,
		       void *buf,
                       uint size);

int tipc_forward2name(__u32 portref, 
		      struct tipc_name const *name, 
		      __u32 domain,   /*0: own zone */
		      unsigned int section_count,
		      struct tipc_msg_section const *msg,
		      struct tipc_portid const *origin,
		      unsigned int importance);

int tipc_forward2port(__u32 portref,
		      struct tipc_portid const *dest,
		      unsigned int section_count,
		      struct tipc_msg_section const *msg,
		      struct tipc_portid const *origin,
		      unsigned int importance);


int
tipc_multicast(__u32 portref, 
               struct tipc_name_seq const *seq, 
               __u32 domain,	/* 0:own zone */
               unsigned int section_count,
               struct tipc_msg_section const *msg);

int
tipc_multicast_buf(__u32 portref, 
		   struct tipc_name_seq const *seq, 
		   __u32 domain,	/* 0:own zone */
		   void *buf,
		   uint size);
/*
 * Subscriptions:
 */

typedef void (*tipc_subscr_event) (void *usr_handle,
				   __u32 subscr_ref,
				   unsigned int event,
				   unsigned int type,
				   unsigned int found_lower,
				   unsigned int found_upper);

int tipc_subscribe(__u32 user,
		   void *usr_handle,
		   unsigned int type,
		   unsigned int lower,
		   unsigned int upper,
		   unsigned int timeout,
                   unsigned int all,
		   tipc_subscr_event event_cb, 
		   __u32 * ref);

int tipc_unsubscribe(__u32 subscr_ref);

int tipc_ispublished(struct tipc_name const *name);

unsigned int tipc_available_nodes(const __u32 scope);


/* 
 * Build interface: (WRS only)
 * ---------------
 */

struct tipc_media_descr {
    int         type;                   /* media type identifier */
    VOIDFUNCPTR start;                  /* media initialization routine */
    VOIDFUNCPTR stop;                   /* media termination routine */
    char *      name;                   /* prefix string ("xyz:") */
    int         priority;               /* default priority */
};

/*
 * Management interface: 
 * --------------------
 *
 * Integers and addresses below are in network byte order. 
 * Character arrays are zero-terminated strings.
 * Send with size = sizeof(struct tipc_command_msg)                      
 */

#define TIPC_MAGIC  0x54495043
#define MAX_BEARER_NAME 48
#define MAX_LINK_NAME   72

#define ETH_ADDR         0
#define SOCKADDR_IPV4    1
#define SOCK_DESCR       2
#define SM_ADDR          3

struct tipc_media_addr {
        __u32  type;
        union{
             struct {
		     __u16 sin_family;
		     __u16 sin_port;
		     struct {
			     __u32 s_addr;
		     }sin_addr;
		     char pad[4];
	     }addr_in;
             __u8   eth_addr[6];
             __u16  sock_descr;
             __u32  sm;         /* 0-20, 0xbbbbbbbb broadcast, WRS-specific */
        }dev_addr;
};


struct tipc_enable_bearer_argv {
	__u32 priority;	/* Range [1,31]. Override per link  */
	__u32 detect_scope;	
	char name[MAX_BEARER_NAME];  /* Format <media:bearer>\0 */
};

struct tipc_create_link_argv {
        __u32   domain;
	struct tipc_media_addr peer_addr;
	char bearer_name[MAX_BEARER_NAME];
};

struct tipc_config_link_argv {
	__u32 value;	/* priority/tolerance/window  */
	char name[MAX_LINK_NAME];
};

struct tipc_get_name_table_argv {
	__u32 depth;	/* 1:type, 2:+port name, 3:+port id, 4+:+debug info */
	__u32 type;	/* 0:all types, unless lowbound or upbound nonzero */
	__u32 lowbound; /* low=0,up=0:all instances, low>0,up=0:low only */
	__u32 upbound;  /* low>0,up>=low:from low to up, low>0,up<low: error */
};

/* 
 * Command Group 1:                          
 * Read-only or non-intrusive commands: May be called from       
 * anywhere by using port name <0,address>. May also be called 
 * via the mangement connection. 
 */
#define  TIPC_GET_PORT_STATISTICS   100u	/* arg: port ref  */
#define  TIPC_RESET_PORT_STATISTICS 101u	/* arg: port ref  */
#define  TIPC_GET_NODES             102u	/* arg: domain     */
#define  TIPC_GET_LINKS             103u	/* arg: domain     */
#define  TIPC_GET_ROUTES            104u	/* arg: domain     */
#define  TIPC_GET_LINK_STATISTICS   105u	/* arg: link name */
#define  TIPC_RESET_LINK_STATISTICS 106u	/* arg: link name */
#define  TIPC_GET_PEER_ADDRESS      107u	/* arg: link name */
#define  TIPC_GET_NAME_TABLE        108u	/* tipc_get_name_table_argv */
#define  TIPC_GET_BEARERS           109u	/* no arg         */
#define  TIPC_GET_MEDIA             110u	/* no arg         */
#define  TIPC_GET_PORTS             111u	/* no arg         */

/* 
 * Command Group 2:                                         
 * "Risky" commands: The first call must be an TIPC_ESTABLISH,
 * sent to <0,address> as above. Upon receiving the confirmation
 * the new connection is used for subsequent commands. 
 * There may only exist one such connection per node at any 
 * time, so by holding on this connection the manager process 
 * can exclude other users from changing the configuration values.
 * The commands return an empty (result_len == 0) confirmation
 * message when successful.
 */

#define  TIPC_ESTABLISH          200u	/* Send first. No arg */
#define  TIPC_CREATE_LINK        201u	/* tipc_create_link_argv    */
#define  TIPC_REMOVE_LINK        202u	/* arg: link name */
#define  TIPC_BLOCK_LINK         203u	/* arg: link name */
#define  TIPC_UNBLOCK_LINK       204u	/* arg: link name */
#define  TIPC_SET_LINK_TOLERANCE 205u	/* tipc_config_link_argv */
#define  TIPC_SET_LINK_PRIORITY  206u	/* tipc_config_link_argv */
#define  TIPC_SET_LINK_WINDOW    207u	/* tipc_config_link_argv */
#define  TIPC_ENABLE_BEARER      208u	/* arg: tipc_enable_bearer_argv */
#define  TIPC_DISABLE_BEARER     209u	/* arg: bearer name    */


/* 
 * Command Group 3:                                              
 * Subscriptions: Establishes a connection associated to 
 * the subscription, confirmed by an empty response message.
 * Thereafter a message is received each time the subsription fires.
 * Sending any message over the connection or deleting the 
 * socket/port causes the subscription to be cancelled.
 * Timed-out subscriptions also abort the connection.
 * Link events are associated with a link name string.
 */

#define  TIPC_NAME_SUBSCRIBE         300u
#define  TIPC_LINK_SUBSCRIBE         302u

/* 
 * Command Group 4:
 * ioctls which can be done on any socket:
 */
#define  TIPC_SET_OWN_NODE          400u    /* arg: __u32 */
#define  TIPC_ENABLE_REMOTE_MNG     401u    /* no argument          */
#define  TIPC_DISABLE_REMOTE_MNG    402u    /* no argument          */
#define  TIPC_SET_MAX_PORTS         403u    /* arg: integer         */
#define  TIPC_GET_MAX_PORTS         404u    /* no argument          */
#define  TIPC_SET_MAX_PUBLICATIONS  405u    /* arg: integer         */
#define  TIPC_GET_MAX_PUBLICATIONS  406u    /* no argument          */
#define  TIPC_SET_MAX_SUBSCRIPTIONS 407u    /* arg: integer         */
#define  TIPC_GET_MAX_SUBSCRIPTIONS 408u    /* no argument          */
#define  TIPC_SET_MAX_ZONES         409u    /* arg: integer         */
#define  TIPC_GET_MAX_ZONES         410u    /* no argument          */
#define  TIPC_SET_MAX_CLUSTERS      411u    /* arg: integer         */
#define  TIPC_GET_MAX_CLUSTERS      412u    /* no argument          */
#define  TIPC_SET_MAX_NODES         413u    /* arg: integer         */
#define  TIPC_GET_MAX_NODES         414u    /* no argument          */
#define  TIPC_SET_MAX_SLAVES        415u    /* arg: integer         */
#define  TIPC_GET_MAX_SLAVES        416u    /* no argument          */
#define  TIPC_SET_NET_ID            417u    /* arg: integer         */
#define  TIPC_GET_NET_ID            418u    /* no argument          */
#define  TIPC_SET_BCAST_THRESHOLD   419u    /* arg: integer         */
#define  TIPC_GET_BCAST_THRESHOLD   420u    /* no argument          */


struct tipc_cmd_msg {
	__u32 magic;
	__u32 cmd;
	char usr_handle[8];
	union {
		__u32 port_ref;
		__u32 domain;
		struct tipc_create_link_argv create_link;
		struct tipc_config_link_argv config_link;
		char link_name[72];
		struct tipc_enable_bearer_argv enable_bearer;
		char bearer_name[32];
		struct tipc_get_name_table_argv get_name_table;
		struct tipc_subscr subscr;
	} argv;
};

#define VAR_ARRAY_SIZE 1

struct tipc_node_info {
        int up;
        __u32 addr;
};

struct tipc_route_info {
        __u32 dest;
	__u32 router;
};

struct tipc_link_info {
	__u32 up;
        __u32 dest;
        char str[MAX_LINK_NAME];
};

struct tipc_cmd_result_msg {
	__u32 cmd;	/* The original command */
	char usr_handle[8];
	int retval;
	__u32 remains;	  /* If more messages to follow */
	__u32 result_len; /* In this message */
	union {
		struct tipc_media_addr peer_address;
		struct tipc_event event;
		struct tipc_node_info nodes[VAR_ARRAY_SIZE];
		struct tipc_route_info routes[VAR_ARRAY_SIZE];
		struct tipc_link_info links[VAR_ARRAY_SIZE];
		char str[VAR_ARRAY_SIZE];
	} result;
};

#endif
